package com.jy.novel.common;

import org.apache.commons.lang.StringUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by jihb on 4/14/16.
 */
public class JdbcHelper {

    JdbcTemplate jdbcTemplate;
    DataSource dataSource;

    private Map<String, SimpleJdbcInsert> jdbcInsertMap = new HashMap();
    /**
     * 分页查询
     * @param sql
     * @param params
     * @param type
     * @param curPage
     * @param pageSize
     * @param <T>
     * @return
     */
    public <T> Page<T> queryForPageBean(String sql,Object[] params,Class<T> type,int curPage,int pageSize){
        if (curPage < 1){
            curPage = 1;
        }
        if (pageSize < 1){
            pageSize = 1;
        }
        Page<T> page = new Page<>();

        //查询记录数
        int rowCount = jdbcTemplate.queryForObject(String.format("select count(*) from (%s) a",sql),params,Integer.class);
        page.setTotalCount(rowCount);
        page.setTotalPage(rowCount%pageSize==0?rowCount/pageSize:(rowCount/pageSize + 1));

        //查询list
        sql = sql+" limit "+(curPage-1)*pageSize+","+pageSize;
        List<T> list = jdbcTemplate.query(sql,BeanPropertyRowMapper.newInstance(type),params);
        page.setResult(list);
        return page;
    }

    /**
     * 分页查询 无参数
     * @param sql
     * @param type
     * @param curPage
     * @param pageSize
     * @param <T>
     * @return
     */
    public <T> Page<T> queryForPageBean(String sql,Class<T> type,int curPage,int pageSize){
        return this.queryForPageBean(sql,null,type,curPage,pageSize);
    }

    /**
     * 分页查询list
     * @param sql
     * @param params
     * @param type
     * @param curPage
     * @param pageSize
     * @param <T>
     * @return
     */
    public <T> List<T> queryForListBean(String sql,Object[] params,Class<T> type,int curPage,int pageSize){
        sql += String.format(" limit %s,%s",(curPage-1)*pageSize,pageSize);
        return jdbcTemplate.query(sql,BeanPropertyRowMapper.newInstance(type),params);
    }

    /**
     * 分页查询list 无参数
     * @param sql
     * @param type
     * @param curPage
     * @param pageSize
     * @param <T>
     * @return
     */
    public <T> List<T> queryForListBean(String sql,Class<T> type,int curPage,int pageSize){
        return this.queryForListBean(sql,new Object[0],type,curPage,pageSize);
    }

    /**
     * 查询list 不分页
     * @param sql
     * @param params
     * @param type
     * @param <T>
     * @return
     */
    public <T> List<T> queryForListBean(String sql,Object[] params,Class<T> type){
        return jdbcTemplate.query(sql,BeanPropertyRowMapper.newInstance(type),params);
    }

    /**
     * 查询list 不分页 无参数
     * @param sql
     * @param type
     * @param <T>
     * @return
     */
    public <T> List<T> queryForListBean(String sql,Class<T> type){
        return jdbcTemplate.query(sql,BeanPropertyRowMapper.newInstance(type));
    }

    /**
     * 根据bean查询单条记录
     * @param sql
     * @param params
     * @param type
     * @param <T>
     * @return
     */
    public <T> T queryForBean(String sql,Object[] params,Class<T> type){
        try {
            return jdbcTemplate.queryForObject(sql, BeanPropertyRowMapper.newInstance(type), params);
        }catch (Exception ex){
            return  null;
        }
    }

    /**
     * 根据bean查询 无参数
     * @param sql
     * @param type
     * @param <T>
     * @return
     */
    public <T> T queryForBean(String sql,Class<T> type){
        try {
            return jdbcTemplate.queryForObject(sql, BeanPropertyRowMapper.newInstance(type));
        }catch (Exception ex){
            return null;
        }
    }

    /**
     * 查询 返回map
     * @param sql
     * @param params
     * @return
     */
    public Map queryForMap(String sql,Object[] params){
        if (params==null || params.length < 1){
            return jdbcTemplate.queryForMap(sql);
        }
        return jdbcTemplate.queryForMap(sql,params);
    }

    /**
     * 查询 返回map 无参数
     * @param sql
     * @return
     */
    public Map queryForMap(String sql){
        return this.queryForMap(sql,null);
    }

    /**
     * 更新操作
     * @param sql
     * @param params
     * @return
     */
    public int update(String sql,Object... params){
        if (params==null || params.length < 1){
            return jdbcTemplate.update(sql);
        }
        return jdbcTemplate.update(sql,params);
    }

    /**
     * 跟新操作 无参数
     * @param sql
     * @return
     */
    public int update(String sql){
        return this.update(sql,null);
    }


    /**
     * 查询 返回Number对象(如查询总数)
     * @param sql
     * @param params
     * @return
     */
    public Number queryForNumber(String sql,Object... params){
        if (params == null || params.length < 1){
            return jdbcTemplate.queryForObject(sql,Number.class);
        }
        return jdbcTemplate.queryForObject(sql,params,Number.class);
    }

    /**
     * 查询 返回Number对象 无参数
     * @param sql
     * @return
     */
    public Number queryForNumber(String sql){
        return this.queryForNumber(sql,null);
    }

    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
        this.dataSource = dataSource;
    }


    public int insert(String sql) {
        return this.jdbcTemplate.update(sql);
    }

    public int insert(String sql, Object[] params) {
        return this.jdbcTemplate.update(sql, params);
    }

    public int[] batchUpdate(String sql, List<Object[]> argList) {
        return this.jdbcTemplate.batchUpdate(sql, argList);
    }

    public int simpleInsert(String tableName, Map<String, Object> fieldValue) {
        SimpleJdbcInsert insert = this.getSimpleJdbcInsert(tableName, (String)null);
        return insert.execute(fieldValue);
    }

    private SimpleJdbcInsert getSimpleJdbcInsert(String tableName, String autoField) {
        String key = String.format("%s[%s]", new Object[]{tableName, autoField});
        SimpleJdbcInsert insert = (SimpleJdbcInsert)this.jdbcInsertMap.get(key);
        if(insert == null) {
            insert = new SimpleJdbcInsert(this.jdbcTemplate);
            insert.withTableName(tableName);
            if(StringUtils.isNotBlank(autoField)) {
                insert.usingGeneratedKeyColumns(new String[]{autoField});
            }

            this.jdbcInsertMap.put(key, insert);
        }

        return insert;
    }

    public Number simpleInsertReturnAutoField(String tableName, Map<String, Object> fieldValue) {
        SimpleJdbcInsert insert = this.getSimpleJdbcInsert(tableName, "id");
        return insert.executeAndReturnKey(fieldValue);
    }
}
